﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using DevComponents.DotNetBar;
using DevComponents.DotNetBar.Controls;
using AMS.Configuration;
using AMS.UI.Controls.Properties;
using AMS.Common;
using AMS.ComponentModel;

namespace AMS.UI.Controls
{
    /// <summary>
    /// 列表组合控件，提供数据绑定，分页，查找定位，浏览等功能的列表控件
    /// </summary>
    [ToolboxBitmap(typeof(DataGridView))]
    public partial class AmsGrid : UserControl
    {
        /// <summary>
        /// 列表组合控件，提供数据绑定，分页，查找定位，浏览等功能的列表控件
        /// </summary>
        public AmsGrid()
        {
            InitializeComponent();
            lblCustomeText.Text = "";
            lblTitle.Text = "";
            gv.SearchTool = new SearchTextBox(txtSearchKey);
            gv.DataSourceChanged += new EventHandler(gv_DataSourceChanged);

            cmbPageSize.Items.Clear();
            cmbPageSize.Items.Add(20);
            cmbPageSize.Items.Add(50);
            cmbPageSize.Items.Add(100);
            cmbPageSize.Items.Add(200);
            cmbPageSize.Items.Add(500);
            cmbPageSize.Items.Add(1000);
            cmbPageSize.SelectedIndex = 1;

            // 事件路由
            gv.SelectedRowChanged += new EventHandler(delegate(object sender, EventArgs e)
                {
                    if(SelectedRowChanged != null)
                    {
                        SelectedRowChanged(sender, e);
                    }
                });

            gv.GridViewRowAdded += new EventHandler<GridViewRowAddEventArgs>(delegate(object sender, GridViewRowAddEventArgs e)
                {
                    if (GridViewRowAdded != null)
                    {
                        GridViewRowAdded(sender, e);
                    }
                });
        }

        #region 属性
        /// <summary>
        /// 当选中的行发生变化的时候
        /// </summary>
        public event EventHandler SelectedRowChanged;
        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<GridViewRowAddEventArgs> GridViewRowAdded;
        /// <summary>
        /// 获取或设置是否显示头部信息
        /// </summary>
        [DefaultValue(true)]
        public bool HeaderVisible
        {
            get { return pnlHeader.Visible; }
            set { pnlHeader.Visible = value; }
        }

        /// <summary>
        /// 获取或设置是否显示脚部信息
        /// </summary>
        [DefaultValue(true)]
        public bool FooterVisible
        {
            get { return pnlFooter.Visible; }
            set { pnlFooter.Visible = value; }
        }

        /// <summary>
        /// 获取或设置标题
        /// </summary>
        public string Caption
        {
            get { return lblTitle.Text; }
            set { lblTitle.Text = value; }
        }

        /// <summary>
        /// 获取或设置是否显示分页控件
        /// </summary>
        [DefaultValue(true)]
        public bool PagerVisible
        {
            get { return pnlPager.Visible; }
            set { pnlPager.Visible = value; }
        }

        /// <summary>
        /// 获取或设置标题的图片，如果没有，则使用默认的图片
        /// </summary>
        public Image CaptionImage
        {
            get { return pbCaption.Image; }
            set { pbCaption.Image = value; }
        }

        /// <summary>
        /// 是否显示checkbox
        /// </summary>
        [DefaultValue(false)]
        public bool ShowCheckBoxes
        {
            get { return gv.ShowCheckBoxes; }
            set { gv.ShowCheckBoxes = value; ; }
        }
        /// <summary>
        /// 是否显示行号
        /// </summary>
        [DefaultValue(false)]
        public bool ShowRowNumbers
        {
            get { return gv.ShowRowNumbers; }
            set { gv.ShowRowNumbers = value; }
        }

        /// <summary>
        /// 获取内部的Grid列表控件
        /// </summary>
        [Browsable(false)]
        public AmsGridView GridView
        {
            get { return gv; }
        }

        /// <summary>
        /// 头
        /// </summary>
        public PanelEx HeadPanel
        {
            get { return pnlHeader; }
        }

        private int recordCount;

        /// <summary>
        /// 获取或设置总记录数，如果不设定，则分页控件不起作用，如果设定的值使得页码超出范围，则会跳转到第0页(初始页)
        /// </summary>
        [Browsable(false)]
        public int RecordCount
        {
            get { return recordCount; }
            set
            {
                recordCount = value;
                if (PagerVisible)
                {
                    lblCount.Text = string.Format("记录总数：{0} / {1}", gv.Rows.Count, value);
                }
                else
                {
                    lblCount.Text = string.Format("记录总数：{0}", value);
                }

                lblCount.Left = pnlHeader.Width - lblCount.Width - 5;
                RefreshPager(false);
            }
        }

        private int _currentPageIndex;
        /// <summary>
        /// 获取或设置当前页码
        /// </summary>
        [DefaultValue(0)]
        [Browsable(false)]
        public int CurrentPageIndex
        {
            get { return _currentPageIndex; }
            set
            {
                if (value == 0 || value == PageCount)
                {
                    _currentPageIndex = value;
                    GotoPage();
                    return;
                }

                if (value < 0 || value >= PageCount)
                {
                    throw new ArgumentOutOfRangeException("value");
                }

                if (_currentPageIndex != value)
                {
                    _currentPageIndex = value;
                    GotoPage();
                }
            }
        }

        /// <summary>
        /// 页码变化的事件
        /// </summary>
        public event EventHandler PageIndexChanged;
        /// <summary>
        /// 页码变化的事件
        /// </summary>
        protected virtual void OnPageIndexChanged()
        {
            if (PageIndexChanged != null && gv.DataSource != null)
            {
                PageIndexChanged(this, EventArgs.Empty);
            }
        }

        private int _pageSize = 50;
        /// <summary>
        /// 获取或设置一页的大小，默认为50，如果设置的值不在列表控件中，会添加到列表中
        /// </summary>
        [DefaultValue(50)]
        public int PageSize
        {
            get { return _pageSize; }
            set
            {
                if (value <= 0)
                {
                    throw new ArgumentException("value不能为0或负数");
                }

                _pageSize = value;
                int index = cmbPageSize.Items.IndexOf((object)_pageSize);
                if (index < 0)
                {
                    index = cmbPageSize.Items.Add((object)_pageSize);
                }

                if (cmbPageSize.SelectedIndex != index)
                {
                    supressPageSizeChangedEvent = true;
                    try
                    {
                        cmbPageSize.SelectedIndex = index;
                    }
                    finally
                    {
                        supressPageSizeChangedEvent = false;
                    }
                }

                CurrentPageIndex = 0;
            }
        }

        /// <summary>
        /// 获取总页数
        /// </summary>
        [Browsable(false)]
        public int PageCount
        {
            get
            {
                if (recordCount == 0 || PageSize == 0)
                {
                    return 0;
                }

                int value = RecordCount / PageSize;
                if (RecordCount % PageSize > 0)
                {
                    value++;
                }

                return value;
            }
        }

        /// <summary>
        /// 是否挂起对PageIndexChanged的事件的处理（即在内部，不处理这类事件）
        /// </summary>
        private bool supressPageIndexChangedEvent;
        /// <summary>
        /// 是否扶起对PageSizeChanged事件的处理
        /// </summary>
        private bool supressPageSizeChangedEvent;
        /// <summary>
        /// 获取绑定的数据源
        /// </summary>
        public object DataSource
        {
            get { return gv.DataSource; }
        }
        #endregion

        #region 初始化和加载
        /// <summary>
        /// 使用配置节点名来初始化列表的表头
        /// </summary>
        /// <param name="configName"></param>
        public void Init(string configName)
        {
            InterfaceConfig config = new InterfaceConfig(AmsEnvironment.GetSystemPath(SystemPath.InterfaceFile));
            try
            {
                ListConfigInfo configInfo = config.GetListConfig(configName);
                if (string.IsNullOrEmpty(Caption))
                {
                    Caption = configInfo.Title;
                }

                gv.Init(configInfo);
            }
            catch (ConfigSectionNotExistException ex)
            {
                MessageBox.Show(ex.Message);
            }
            catch (ConfigException ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 让列表处于预备加载的状态
        /// </summary>
        public void Preload()
        {
            gv.Visible = false;
            ShowLoading();
        }

        /// <summary>
        /// 对列表进行数据绑定。使用的数据必需是DataTable，或实现了IEnumerable接口的数据集合
        /// </summary>
        /// <param name="data"></param>
        public void DataBind(object data)
        {
            int count = TryGetDataSourceCount(data);
            if (count > 1000 || count < 0)
            {
                gv.Visible = false;
                pbLoading.Visible = false;
                ShowLoading();
            }

            try
            {
                gv.DataBind(data);
                if (!PagerVisible)
                {
                    RecordCount = gv.Rows.Count;
                }
            }
            finally
            {
                gv.Visible = true;
                pbLoading.Visible = false;
                RefreshNavigateControls();
            }
        }

        private int TryGetDataSourceCount(object data)
        {
            if (data == null)
            {
                return 0;
            }
            if (data is System.Collections.IList)
            {
                return (data as System.Collections.IList).Count;
            }
            if (data is IListSource)
            {
                return (data as IListSource).GetList().Count;
            }

            return -1;
        }

        private void ShowLoading()
        {
            if (pbLoading.Image == null)
            {
                pbLoading.Image = Resources.loading;
            }

            pbLoading.Left = (Width - pbLoading.Width) / 2;
            pbLoading.Top = pnlHeader.Height + (gv.Height - pbLoading.Height) / 2;
            pbLoading.Visible = true;
            Application.DoEvents();
        }

        void gv_DataSourceChanged(object sender, EventArgs e)
        {
            btnNavFirst.Enabled = false;
            btnNavPrev.Enabled = false;
            if (gv.DataSource == null)
            {
                btnNavLast.Enabled = false;
                btnNavNext.Enabled = false;
            }
            else
            {
                if (gv.Rows.Count > 0 && gv.Columns.Count > 0)
                {
                    gv.CurrentCell = gv.Rows[0].Cells[0];
                }
            }
        }
        #endregion

        #region 分页相关
        /// <summary>
        /// 设置了相关的参数后重新设置分页信息
        /// </summary>
        private void RefreshPager(bool resetCurrentPage)
        {
            if (!PagerVisible)
            {
                return;
            }

            if (PageSize == 0)
            {
                return;
            }

            int pageCount = RecordCount / PageSize;
            if (RecordCount % PageSize != 0)
            {
                pageCount++;
            }

            int savedSelectedIndex = cmbPageIndex.SelectedIndex;
            cmbPageIndex.Items.Clear();
            for (int i = 1; i <= pageCount; i++)
            {
                cmbPageIndex.Items.Add((object)i);
            }

            if (cmbPageIndex.Items.Count > 0)
            {
                int newSelectedIndex = 0;
                if (!resetCurrentPage)
                {
                    if (savedSelectedIndex >= 0 && savedSelectedIndex < cmbPageIndex.Items.Count)
                    {
                        newSelectedIndex = savedSelectedIndex;
                    }
                }

                supressPageIndexChangedEvent = true;
                try
                {
                    cmbPageIndex.SelectedIndex = newSelectedIndex;
                    //lkPagePrev.Enabled = newSelectedIndex > 0;
                    //lkPageNext.Enabled = newSelectedIndex < PageCount - 1;
                }
                finally
                {
                    supressPageIndexChangedEvent = false;
                }
            }
        }

        private void GotoPage()
        {
            //lkPagePrev.Enabled = _currentPageIndex > 0;
            //lkPageNext.Enabled = _currentPageIndex < PageCount - 1;
            supressPageIndexChangedEvent = true;
            if (_currentPageIndex < cmbPageIndex.Items.Count)
            {
                cmbPageIndex.SelectedIndex = _currentPageIndex;
            }

            supressPageIndexChangedEvent = false;
            OnPageIndexChanged();
        }

        private void cmbPageIndex_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!supressPageIndexChangedEvent)
            {
                CurrentPageIndex = cmbPageIndex.SelectedIndex;
            }
        }

        private void cmbPageSize_SelectedIndexChanged(object sender, EventArgs e)
        {
            // 重置pageIndex, 并重新加载数据
            if (!supressPageSizeChangedEvent)
            {
                PageSize = (int)cmbPageSize.SelectedItem;
            }
        }

        #endregion

        #region 更多操作的管理
        /// <summary>
        /// 添加一个操作
        /// </summary>
        /// <param name="text"></param>
        /// <param name="key"></param>
        /// <param name="tag"></param>
        /// <returns></returns>
        public ButtonItem AddOperation(string text, string key, object tag)
        {
            ButtonItem btn = new ButtonItem();
            btn.Name = "_btn_inner_" + key;
            btn.Text = text;
            btnOp.SubItems.Add(btn);
            return btn;
        }

        /// <summary>
        /// 插入一个操作
        /// </summary>
        /// <param name="index"></param>
        /// <param name="text"></param>
        /// <param name="key"></param>
        /// <param name="tag"></param>
        /// <returns></returns>
        public ButtonItem InsertOperation(int index, string text, string key, object tag)
        {
            ButtonItem btn = new ButtonItem();
            btn.Name = "_btn_inner_" + key;
            btn.Text = text;
            btnOp.SubItems.Insert(index, btn);
            return btn;
        }

        /// <summary>
        /// 获取操作按钮对应的Key值，这个值是创建的时候给定的
        /// </summary>
        /// <param name="button"></param>
        /// <returns></returns>
        public string GetOperationButtonKey(ButtonItem button)
        {
            return button.Name.Replace("_btn_inner_", "");
        }
        #endregion

        private void lblCount_SizeChanged(object sender, EventArgs e)
        {
            lblCount.Left = Width - lblCount.Width - 5;
        }

        private void btnNav_Click(object sender, EventArgs e)
        {
            if (gv.Rows.Count == 0)
            {
                return;
            }

            ButtonItem btn = sender as ButtonItem;
            string tag = btn.Tag.ToString();
            int rowIndex = gv.CurrentCell == null ? -1 : gv.CurrentCell.RowIndex;
            int columnIndex = gv.CurrentCell == null ? 0 : gv.CurrentCell.ColumnIndex;

            switch (tag)
            {
                case "0":
                    rowIndex = 0;
                    break;

                case "1":
                    rowIndex--;
                    break;

                case "2":
                    rowIndex++;
                    break;

                case "3":
                    rowIndex = gv.Rows.Count - 1;
                    break;
            }

            if (rowIndex >= 0 && rowIndex < gv.Rows.Count)
            {
                gv.CurrentCell = gv.Rows[rowIndex].Cells[columnIndex];
            }

            btnNavFirst.Enabled = rowIndex > 0;
            btnNavPrev.Enabled = btnNavFirst.Enabled;
            btnNavLast.Enabled = rowIndex < gv.Rows.Count - 1;
            btnNavNext.Enabled = btnNavLast.Enabled;
        }

        private void btnSelectAll_Click(object sender, EventArgs e)
        {
            if (gv.Rows.Count == 0)
            {
                return;
            }

            btnSelectAll.Checked = !btnSelectAll.Checked;
            gv.CheckAll(btnSelectAll.Checked);
        }

        private void lkPagePrev_Click(object sender, EventArgs e)
        {
            CurrentPageIndex--;
        }

        private void lkPageNext_Click(object sender, EventArgs e)
        {
            CurrentPageIndex++;
        }

        #region 封装的API
        /// <summary>
        /// 获取选中的行的第一行数据
        /// </summary>
        [Browsable(false)]
        public DataGridViewRow SelectedRow
        {
            get
            {
                if (gv.SelectedRows != null && gv.SelectedRows.Count > 0)
                {
                    return gv.SelectedRows[0];
                }

                return null;
            }
        }

        /// <summary>
        /// 获取指定行的内容
        /// </summary>
        /// <returns></returns>
        public string[] SelectedRowContent()
        {
            DataGridViewRow selectedRow = SelectedRow;
            if (selectedRow == null)
            {
                return null;
            }

            List<string> strings = new List<string>();
            for (int i = 0; i < selectedRow.Cells.Count; i++)
            {
                strings.Add(selectedRow.Cells[i].Value as string);
            }

            return strings.ToArray();
        }
        /// <summary>
        /// 获取选中的行的数据在转换成数据源（DataSource）中的行索引
        /// </summary>
        /// <returns></returns>
        public int GetSelectedRowDataIndex()
        {
            return gv.GetSelectedRowDataIndex();
        }
        #endregion

        private void gv_SelectedRowChanged(object sender, EventArgs e)
        {
            RefreshNavigateControls();
        }

        /// <summary>
        /// 
        /// </summary>
        public void RefreshNavigateControls()
        {
            btnNavFirst.Enabled = gv.CurrentCell != null && (gv.CurrentCell.RowIndex > 0);
            btnNavLast.Enabled = gv.CurrentCell != null && (gv.CurrentCell.RowIndex < gv.Rows.Count - 1);
            btnNavNext.Enabled = btnNavLast.Enabled;
            btnNavPrev.Enabled = btnNavFirst.Enabled;
        }

        private void btnExport_Click(object sender, EventArgs e)
        {
            IExporter exporter = TypePool.CreateInstance("Exporter") as IExporter;
            if (exporter == null)
            {
                throw new AmsException(LocaleFramework.GetFormattedString("@TypeNotFoundInTypePool", "IExporter"));
            }

            exporter.Config = gv.Config;
            exporter.DataSource = gv.DataSource;
            // TODO: 需要给定datasoure名称
            exporter.DataSourceName = gv.Config.SectionName;
            exporter.ExporterCaption = lblTitle.Text;
            exporter.Export();
        }
    }
}
